<ul>
<?php

function getFiles($in_path, $in_finfo)
{
	$ret = array();
	$dh = opendir($in_path);
	if (!$dh) {
		print '// opendir failed';
		exit;
	}
	while (($fname = readdir($dh)) !== FALSE) {
		if (($fname == '.') || ($fname == '..')) {
			continue;
		}
		$path = "{$in_path}/{$fname}";
		if (is_dir($path)) {
			$ret[$fname] = array('p' => $path, 'c' => getFiles($path, $in_finfo), 't' => NULL);
		} elseif (is_file($path)) {
			$ret[$fname] = array('p' => $path, 'c' => NULL, 't' => finfo_file($in_finfo, realpath($path)));
		}
	}
	closedir($dh);
	uasort($ret, function($e1, $e2) {
		if ($e1['c'] && !$e2['c']) {
			return -1;
		}
		if (!$e1['c'] && $e2['c']) {
			return 1;
		}
		return strcasecmp($e1['p'], $e2['p']);
	});
	return $ret;
}

function makeLinks($in_tree, $in_open)
{
	if ($in_open > 0) {
		$display = 'block';
		$state = 'open';
	} else {
		$display = 'none';
		$state = 'close';
	}
	foreach ($in_tree as $key => $val) {
		if ($val['c']) {
			print "<li><folder state='{$state}' onclick='action(this)'></folder> <span>{$key}</span>\n";
			print "<ul style='display:{$display};'>\n";
			makeLinks($val['c'], ($in_open - 1));
			print "</ul>\n";
			print "</li>\n";
		} else {
			print "<li><file type='{$val['t']}'></file> <a href='{$val['p']}'>{$key}</a></li>\n";
		}
	}
}

$FINFO = finfo_open(FILEINFO_MIME_TYPE);
makeLinks(getFiles('..', $FINFO), array_key_exists('o', $_GET) ? $_GET['o'] : 0);
finfo_close($FINFO);

?>
</ul>
<style type='text/css'>

BUTTON {
	border: solid 1px silver;
	color: gray;
	font-family: monospace;
	padding: 3px;
}
UL {
	list-style-type: none;
}
FOLDER:hover {
	cursor: pointer;
}
</style>
<script>

var icon = {
	uris : {
		folderClose : '',
		folderOpen : '',
		fileGeneric : '',
		fileImage : '',
		fileText : ''
	},
	createImg : function(in_name, in_wh) {
		var img = document.createElement('IMG');
		with (img) {
			src = this.uris[in_name];
			width = in_wh;
			height = in_wh;
		}
		return img;
	}
}

function action(in_elem)
{
	var ul = in_elem.parentNode.getElementsByTagName('UL')[0];
	if (ul.style.display == 'none') {
		in_elem.firstChild.src = icon.uris.folderOpen;
		ul.style.display = 'block';
	} else {
		in_elem.firstChild.src = icon.uris.folderClose;
		ul.style.display = 'none';
	}
}

var iconSize = 16;
var folders = document.getElementsByTagName('FOLDER');
for (var i = 0; i < folders.length; i++) {
	if (folders[i].getAttribute('state') == 'open') {
		folders[i].appendChild(icon.createImg('folderOpen', iconSize));
	} else {
		folders[i].appendChild(icon.createImg('folderClose', iconSize));
	}
}
var files = document.getElementsByTagName('FILE');
for (var i = 0; i < files.length; i++) {
	var type = files[i].getAttribute('type').split('/')[0];
	switch (type) {
	case 'image' :
		files[i].appendChild(icon.createImg('fileImage', iconSize));
		break;
	case 'text' :
		files[i].appendChild(icon.createImg('fileText', iconSize));
		break;
	default :
		files[i].appendChild(icon.createImg('fileGeneric', iconSize));
		break;
	}
}
</script>
